#include "./../inc/snake.h"

Snake *Snake::m_instance = NULL;

Snake::~Snake()
{
}

// 初始化蛇的初始位置
void Snake::init(int x, int y)
{
    direction = RIGHT;
    isConfused = false;
    m_snakeBody.clear(); // 清空蛇身

    m_snakeBody.push_back(Point((x * GRID_SIZE) + MAP_START_X, y * GRID_SIZE));
    m_snakeBody.push_back(Point(((x - 1) * GRID_SIZE) + MAP_START_X, y * GRID_SIZE));

    show();
}

void Snake::show()
{
    if (m_snakeBody.empty())
    {
        return; // 蛇身为空时不绘制
    }

    for (auto i : m_snakeBody)
    {
        if (i == m_snakeBody.front())
        {
            switch (direction)
            {
            case UP:
                head_up.showIcon(mp, i.x(), i.y());
                break;
            case DOWN:
                head_down.showIcon(mp, i.x(), i.y());
                break;
            case LEFT:
                head_left.showIcon(mp, i.x(), i.y());
                break;
            case RIGHT:
                head_right.showIcon(mp, i.x(), i.y());
                break;
            }
            continue;
        }
        else if (i == m_snakeBody.back())
        {
            switch (direction)
            {
            case UP:
                tail_up.showIcon(mp, i.x(), i.y());
                break;
            case DOWN:
                tail_down.showIcon(mp, i.x(), i.y());
                break;
            case LEFT:
                tail_left.showIcon(mp, i.x(), i.y());
                break;
            case RIGHT:
                tail_right.showIcon(mp, i.x(), i.y());
                break;
            }
            continue;
        }
        body.show(mp, i.x(), i.y());
    }
}

void Snake::move(GameMap *map, int &score, int &speed, bool &isGameOver, int max_speed, int min_speed, bool &is_create_ai_snake)
{
    if (m_snakeBody.empty())
    {
        isGameOver = true; // 蛇为空，游戏结束
        return;
    }

    // 计算新蛇头位置
    Point newHead = calculateNewHead();

    // 检测碰撞（墙/自身）
    if (isCollision(newHead, map))
    {
        std::cout << "Game Over!" << std::endl;
        isGameOver = true; // 碰撞，游戏结束
        return;
    }

    // 处理移动（吃食物/正常移动）
    handleMovement(newHead, map, score, speed, isGameOver, max_speed, min_speed, is_create_ai_snake);
}

// 计算新蛇头位置
Point Snake::calculateNewHead()
{
    Point head = m_snakeBody.front();
    int newX = head.x();
    int newY = head.y();

    switch (direction)
    {
    case UP:
        newY -= GRID_SIZE;
        break;
    case DOWN:
        newY += GRID_SIZE;
        break;
    case LEFT:
        newX -= GRID_SIZE;
        break;
    case RIGHT:
        newX += GRID_SIZE;
        break;
    }

    return Point(newX, newY);
}

// 检测新蛇头是否碰撞（墙或自身）
bool Snake::isCollision(const Point &newHead, GameMap *map)
{
    int newX = newHead.x();
    int newY = newHead.y();

    //  撞墙检测
    if (newX < MAP_START_X || newX >= MAP_START_X + MAP_WIDTH ||
        newY < 0 || newY >= MAP_HEIGHT)
    {
        return true;
    }

    // 撞自身检测（检查新位置是否是蛇身）
    int headRow = newY / GRID_SIZE;
    int headCol = (newX - MAP_START_X) / GRID_SIZE;
    if (map->getGrid()[headRow][headCol] == GRID_SNAKE_BODY || map->getGrid()[headRow][headCol] == GRID_AI_SNAKE_BODY)
    {
        return true;
    }

    return false;
}

// 处理移动核心逻辑（添加新头、处理食物、删除尾）
void Snake::handleMovement(const Point &newHead, GameMap *map, int &score, int &speed, bool &isGameOver, int max_speed, int min_speed, bool &is_create_ai_snake)
{
    int newX = newHead.x();
    int newY = newHead.y();
    int headRow = newY / GRID_SIZE;
    int headCol = (newX - MAP_START_X) / GRID_SIZE;

    // 先获取新位置的类型
    GridState newPosType = static_cast<GridState>(map->getGrid()[headRow][headCol]);

    // 处理食物效果
    bool ateFood = handleFood(newPosType, map, score, speed, isGameOver, max_speed, min_speed, is_create_ai_snake);
    if (isGameOver)
        return; // 若吃炸弹导致游戏结束，直接返回

    // 添加新蛇头
    body.show(mp, m_snakeBody.front().x(), m_snakeBody.front().y()); // 将原本的蛇头显示为蛇身
    m_snakeBody.push_front(newHead);
    map->getGrid()[headRow][headCol] = GRID_SNAKE_BODY; // 标记为蛇身

    // 没吃到食物则删除尾（保持长度）
    if (!ateFood)
    {
        removeTail(map);
    }
    else
    {
        map->generateRandomFood(); // 生成新食物
    }

    // 绘制新蛇头 和 新蛇尾
    switch (direction)
    {
    case UP:
        head_up.showIcon(mp, newX, newY);
        break;
    case DOWN:
        head_down.showIcon(mp, newX, newY);
        break;
    case LEFT:
        head_left.showIcon(mp, newX, newY);
        break;
    case RIGHT:
        head_right.showIcon(mp, newX, newY);
        break;
    }

    if (m_snakeBody.size() >= 2)
    {
        // 蛇尾（最后一节）
        auto it = m_snakeBody.end();
        --it;
        Point tail = *it;
        int tailX = tail.x();
        int tailY = tail.y();

        --it;

        // 蛇尾的前一节（倒数第二节，决定蛇尾方向）
        Point prevSegment = *it;
        int prevX = prevSegment.x();
        int prevY = prevSegment.y();

        // 根据前一节与蛇尾的相对位置，判断蛇尾方向
        map->getMap().local_show(mp, tail.x(), tail.y(), tail.x() - MAP_START_X, tail.y(), GRID_SIZE, GRID_SIZE);
        if (prevY < tailY)
        {
            // 前一节在蛇尾上方 → 蛇尾朝上（尾部指向上方，跟随前一节）
            tail_up.showIcon(mp, tailX, tailY);
        }
        else if (prevY > tailY)
        {
            // 前一节在蛇尾下方 → 蛇尾朝下
            tail_down.showIcon(mp, tailX, tailY);
        }
        else if (prevX < tailX)
        {
            // 前一节在蛇尾左侧 → 蛇尾朝左（同y轴，x更小）
            tail_left.showIcon(mp, tailX, tailY);
        }
        else if (prevX > tailX)
        {
            // 前一节在蛇尾右侧 → 蛇尾朝右（同y轴，x更大）
            tail_right.showIcon(mp, tailX, tailY);
        }
    }
    // show();
}

// 处理吃到食物的效果
bool Snake::handleFood(GridState foodType, GameMap *map, int &score, int &speed, bool &isGameOver, int max_speed, int min_speed, bool &is_create_ai_snake)
{
    if (foodType != GRID_EMPTY && foodType != GRID_FOOD_BOMB)
    {
        map->getFoodCount()--;
    }

    switch (foodType)
    {
    case GRID_FOOD_SCORE_1:
        score += 5;
        return true;
    case GRID_FOOD_SCORE_2:
        score += 10;
        return true;
    case GRID_FOOD_SPEED_UP:
        score += 5;
        speed = std::max(max_speed, speed - 1);
        return true;
    case GRID_FOOD_SPEED_DOWN:
        score += 5;
        speed = std::min(min_speed, speed + 1); // 最高500ms
        return true;
    case GRID_FOOD_CONFUSE:
        score += 5;
        isConfused = !isConfused; // 切换方向混淆状态
        return true;
    case GRID_FOOD_BOMB:
        handleBomb(map, isGameOver); // 单独处理炸弹逻辑
        return false;
    case GRID_FOOD_AI_SNAKE:
        score += 10;
        is_create_ai_snake = true; // 生成AI蛇
        return true;
    default:
        return false; // 没吃到食物
    }
}

// 处理炸弹效果（缩短蛇身）
void Snake::handleBomb(GameMap *map, bool &isGameOver)
{
    // 至少保留1个头
    if (m_snakeBody.size() <= 3)
    {
        isGameOver = true; // 游戏结束
        return;
    }

    // 缩短1格（因为刚加了新头，需删除2个尾）
    for (int i = 0; i < 2 && m_snakeBody.size() > 1; i++)
    {
        Point tail = m_snakeBody.back();
        int tRow = tail.y() / GRID_SIZE;
        int tCol = (tail.x() - MAP_START_X) / GRID_SIZE;

        // 清除尾的网格标记和显示
        map->getGrid()[tRow][tCol] = GRID_EMPTY;
        map->getMap().local_show(mp, tail.x(), tail.y(), tail.x() - MAP_START_X, tail.y(), GRID_SIZE, GRID_SIZE);

        m_snakeBody.pop_back();
    }
}

// 移除蛇尾
void Snake::removeTail(GameMap *map)
{
    Point tail = m_snakeBody.back();
    int tailRow = tail.y() / GRID_SIZE;
    int tailCol = (tail.x() - MAP_START_X) / GRID_SIZE;

    // 清除尾的显示（背景覆盖）和网格标记
    map->getMap().local_show(mp, tail.x(), tail.y(), tail.x() - MAP_START_X, tail.y(), GRID_SIZE, GRID_SIZE);
    map->getGrid()[tailRow][tailCol] = GRID_EMPTY;

    m_snakeBody.pop_back();
}

void Snake::setDirection(int newDirection)
{
    int actualDir = newDirection;
    if (isConfused)
    {
        switch (newDirection)
        {
        case UP:
            actualDir = DOWN;
            break;
        case DOWN:
            actualDir = UP;
            break;
        case LEFT:
            actualDir = RIGHT;
            break;
        case RIGHT:
            actualDir = LEFT;
            break;
        default:
            return; // 无效方向不处理
        }
    }

    // 防止直接反向移动（比如不能从右直接转到左）
    if ((direction == UP && actualDir == DOWN) ||
        (direction == DOWN && actualDir == UP) ||
        (direction == LEFT && actualDir == RIGHT) ||
        (direction == RIGHT && actualDir == LEFT))
    {
        return; // 忽略反向移动
    }

    direction = actualDir;
}

Snake *Snake::instance(int *mp)
{
    // 如果没有实例则创建实例
    if (m_instance == NULL)
    {
        m_instance = new Snake(mp);
    }
    return m_instance;
}

void Snake::delInstance()
{
    // 释放实例空间
    delete m_instance;
    m_instance = NULL;
}

Point Snake::getHeadPosition()
{
    if (m_snakeBody.empty())
    {
        return Point(-1, -1);
    }
    return m_snakeBody.front();
}